package com.raycloud.manager.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.raycloud.common.Constants;
import com.raycloud.dao.MsgDao;
import com.raycloud.dao.MsgIndexDao;
import com.raycloud.dao.MsgRelationDao;
import com.raycloud.dao.UserDao;
import com.raycloud.dao.dbhash.DbHashUtil;
import com.raycloud.domain.Msg;
import com.raycloud.domain.MsgDistributeJob;
import com.raycloud.domain.MsgIndex;
import com.raycloud.domain.MsgRelation;
import com.raycloud.domain.User;
import com.raycloud.manager.MsgMgr;
import com.raycloud.manager.msgqueue.IMsgQueueCreator;

public class MsgMgrImpl implements MsgMgr {
	private MsgIndexDao msgIndexDao;
	private MsgDao msgDao;
	private UserDao userDao;
	private MsgRelationDao msgRelationDao;

	private IMsgQueueCreator msgQueueCreator;

	public void setMsgIndexDao(MsgIndexDao msgIndexDao) {
		this.msgIndexDao = msgIndexDao;
	}

	public void setMsgDao(MsgDao msgDao) {
		this.msgDao = msgDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public void setMsgRelationDao(MsgRelationDao msgRelationDao) {
		this.msgRelationDao = msgRelationDao;
	}

	public IMsgQueueCreator getMsgQueueCreator() {
		return msgQueueCreator;
	}

	public void setMsgQueueCreator(IMsgQueueCreator msgQueueCreator) {
		this.msgQueueCreator = msgQueueCreator;
	}

	public void publishOriginalMsg(Msg msg, User user) {
		MsgIndex msgIndex = new MsgIndex(user.getId(), user.getId(),
				msg.getMsgId(), new Date());
		msgIndex.setDbId(DbHashUtil.getMsgIndex(user.getId()));
		msgDao.insertMsg(msg);
		msgIndexDao.insertMsgIndex(msgIndex);
		userDao.updateFieldCount(user.getId(), 1, "msg");

		MsgDistributeJob job = new MsgDistributeJob();
		job.setMsgId(msg.getMsgId());
		job.setUserId(user.getId());
		msgQueueCreator.createJob(job);
	}

	public void publishTransferMsg(Msg msg, MsgRelation msgRelation, User user) {
		MsgIndex msgIndex = new MsgIndex(user.getId(), user.getId(),
				msg.getMsgId(), new Date());
		msgIndex.setDbId(DbHashUtil.getMsgIndex(user.getId()));
		msgDao.insertMsg(msg);
		msgIndexDao.insertMsgIndex(msgIndex);
		userDao.updateFieldCount(user.getId(), 1, "msg");
		msgDao.updateCount(1, msgRelation.getReferencedMsgId(), "transfer");
		msgRelationDao.insertMsgRelation(msgRelation);
		
		MsgDistributeJob job = new MsgDistributeJob();
		job.setMsgId(msg.getMsgId());
		job.setUserId(user.getId());
		msgQueueCreator.createJob(job);
	}

	public List<Msg> queryUserMsgs(User user, int firstResult, int maxResults) {
		long userId = user.getId();
		String msgIndexDbId = DbHashUtil.getMsgIndex(userId);
		List<MsgIndex> msgIndexs = msgIndexDao.queryMsgIndexs(userId,
				firstResult, maxResults, msgIndexDbId);
		if (msgIndexs != null && msgIndexs.size() > 0) {
			List<String> msgIds = new ArrayList<String>();
			for (MsgIndex msgIndex : msgIndexs) {
				msgIds.add(msgIndex.getMsgId());
			}
			List<Msg> msgs = msgDao.queryMsgWidthIds(msgIds);
			
			//如果是转发微博需要把转发微博的原消息查出
			if(msgs != null && msgs.size() > 0) {
				//Map<String, List<String>> transferMsgIdsMap = new HashMap<String, List<String>>();
				//这里一条一条查询，是因为数据库的设计冗余不够好。所以暂时提出问题，后面解决问题
				for(Msg msg : msgs) {
					if(msg.getType() == Constants.FORWARD) {
						String msgRelationDbId = DbHashUtil.getMsgRelationDBId(msg.getUserId());
						Msg transferMsg = msgDao.getMsgWidthWidthReferenceMsgId(msg.getMsgId(), msgRelationDbId);
						msg.setTransferMsg(transferMsg);
					}
				}
				
				//对在同一个DB中的msgRelation归类，这样只要去DB中查一次就可以了。不然要一条一条去查转发微博的元数据
//				if(transferMsgIdsMap.size() > 0) {
//					List<Msg> allTransferMsgs = new ArrayList<Msg>();
//					Set<String> keySet = transferMsgIdsMap.keySet();
//					for(String dbId : keySet) {
//						List<String> transferMsgIdList = transferMsgIdsMap.get(dbId);
//						List<Msg> msgList = msgDao.queryMsgWidthReferenceMsgId(transferMsgIdList, dbId);
//						if(msgList != null) {
//							allTransferMsgs.addAll(msgList);
//						}
//					}
//					
//					Map<String, Msg> allTransferMsgMap = new HashMap<String, Msg>();
//					for (Msg msg : allTransferMsgs) {
//						allTransferMsgMap.put(msg.getMsgId(), msg);
//					}
//					
//					for(Msg msg : msgs) {
//						if(msg.getType() == Constants.FORWARD) {
//							
//						}
//					}
//				}
			}
			
			return msgs;
		}
		return null;
	}

	public Msg getMsgById(String msgId) {
		return msgDao.getMsgById(msgId);
	}

	
}
